/*
 * Copyright 2010-2011 WebEqua Team
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.mathcloud.math.core.matlab.quantity;

//import classes slf4j
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;

//import classes org.webequa.core
import org.webequa.core.common.quantity.ComplexNumber;
import org.webequa.core.common.quantity.RealNumber;
import org.webequa.core.generic.signature.GenericQuantityObjectSignature;

//import classes com.mathworks.toolbox.javabuilder
import com.mathworks.toolbox.javabuilder.MWArray;
import com.mathworks.toolbox.javabuilder.MWCharArray;
import com.mathworks.toolbox.javabuilder.MWClassID;
import com.mathworks.toolbox.javabuilder.MWNumericArray;

public class MatlabComplexNumber extends MatlabQuantityObject implements ComplexNumber
{
	public MatlabComplexNumber()
	{
		super();
		try {
			mtlbObject =  new MWNumericArray(0, 0, MWClassID.DOUBLE);
			log.info("{}={}",mtlbVarName,mtlbObject.toString());
		}
		catch(Exception e) {
			log.error("Exception:",e);
		}
		
		signature = GenericQuantityObjectSignature.getComplexNumberSignature();
		signature.setRealizationName("matlab");
	}

	public MatlabComplexNumber(double real, double image)
	{
		super();
		try {
			mtlbObject =  new MWNumericArray(real, image, MWClassID.DOUBLE);
			log.info("{}={}",mtlbVarName,mtlbObject.toString());
		}
		catch(Exception e) {
			log.error("Exception:",e);
		}
		
		signature = GenericQuantityObjectSignature.getComplexNumberSignature();
		signature.setRealizationName("matlab");
	}

	public MatlabComplexNumber(RealNumber in)
	{
		super();
		try {
			mtlbObject =  new MWNumericArray((double)in.getValue(), 0, MWClassID.DOUBLE);
			log.info("{}={}",mtlbVarName,mtlbObject.toString());
		}
		catch(Exception e) {
			log.error("Exception:",e);
		}
		
		signature = GenericQuantityObjectSignature.getComplexNumberSignature();
		signature.setRealizationName("matlab");
	}

	public MatlabComplexNumber(ComplexNumber in)
	{
		super();
		try {
			mtlbObject =  new MWNumericArray((double)in.getRealPart(), (double)in.getImagePart(), MWClassID.DOUBLE);
			log.info("{}={}",mtlbVarName,mtlbObject.toString());
		}
		catch(Exception e) {
			log.error("Exception:",e);
		}
		
		signature = GenericQuantityObjectSignature.getComplexNumberSignature();
		signature.setRealizationName("matlab");
	}
	
	@Override
	public Double getArg()
	{ 
		Double d 					= null;
		MWCharArray nameFunction 	= null;
		Object[] result 			= null;
		
		try
		{
			log.debug("Work with 'angle' funtion Matlab");
			nameFunction = new MWCharArray("angle");
			result = mtlbEngine.Matlab4WebEqua(1,nameFunction,mtlbObject);
			log.debug("getDouble from 'angle' result");
			d = ((MWNumericArray)result[0]).getDouble(); 
		} catch (Exception e)
		{
			log.error("Exception:",e);
		} finally
	    {
	         /* Free native resources */
	         MWArray.disposeArray(nameFunction);
	         MWArray.disposeArray(result);
	    }
		return d;
	}

	@Override
	public Double getImagePart()
	{
		if (mtlbObject!=null)
			try
			{
				return ((MWNumericArray)mtlbObject).getImagDouble(1);
			} catch (Exception e)
			{
				log.error("Exception:",e);
			}
		else {
			log.warn("The object isn't defined");
		}
		return null;
	}

	@Override
	public Double getMod()
	{
		Double d = null;
		MWCharArray nameFunction = null;
		Object[] result = null;
		
		try
		{
			log.debug("Work with 'abs' funtion Matlab");
			nameFunction = new MWCharArray("abs");
			result = mtlbEngine.Matlab4WebEqua(1,nameFunction,mtlbObject);
			log.debug("getDouble from 'abs' result");
			d = ((MWNumericArray)result[0]).getDouble();
			
		} catch (Exception e)
		{
			log.error("Exception:",e);
		} finally
	    {
	         /* Free native resources */
	         MWArray.disposeArray(nameFunction);
	         MWArray.disposeArray(result);
	    }
		return d;
	}

	@Override
	public Double getRealPart()
	{
		if (mtlbObject!=null)
			try
			{
				return ((MWNumericArray)mtlbObject).getDouble(1);
			} catch (Exception e)
			{
				log.error("Exception:",e);
			}
		else {
			log.warn("The object isn't defined");
		}
		return null;
	}

	@Override
	public Double getValue()
	{
		log.debug("Return modul complex");
		return getMod();
	}

	@Override
	public void setRealPart(double arg0)
	{
			try
			{	
				log.debug("Change real part of {}", mtlbVarName);
				((MWNumericArray)mtlbObject).set(1, arg0);
				log.info("{}={}",mtlbVarName,mtlbObject.toString());
			} catch (Exception e)
			{
				log.error("Exception:",e);
			}
	}
	
	@Override
	public void setImagePart(double arg0)
	{
		try
		{	log.debug("Change image part of {}", mtlbVarName);
			((MWNumericArray)mtlbObject).setImag(1, arg0);
			log.info("{}={}",mtlbVarName,mtlbObject.toString());
		} catch (Exception e)
		{
			log.error("Exception:",e);
		}
	}
	
	@Override
	public void setArg(double arg0)
	{
		try 
		{
			double real = getMod()*Math.cos(arg0);
			double image = getMod()*Math.sin(arg0);
			setRealPart(real);
			setImagePart(image);
		} catch (Exception e)
		{
			log.error("Exception:",e);
		}	
		
	}

	@Override
	public void setMod(double arg0)
	{
		try 
		{
			double real  = arg0*Math.cos(getArg());
			double image = arg0*Math.sin(getArg());
			setRealPart(real);
			setImagePart(image);
		} catch (Exception e)
		{
			log.error("Exception:",e);
		}	
	}

	@Override
	public void setValue(double arg0)
	{
		log.debug("Set modul complex");
		setMod(arg0);		
	}
	
	private static final Logger log = LoggerFactory.getLogger(MatlabComplexNumber.class);
}
